#!/usr/bin/python
# -*- coding: utf-8 -*-
# Script de fonction permettant de manipuler
# les données de ma station météo
# Fabien Marteau
# BeerWare license
# 31 mars 2008
#
# TODO: 
# - time axis in human readable value
# - on server -> png
# - bar graph days fonction

__doc__ = "Data weather manipulation need pylab, tar, numpy, scipy, wget"
__version__ = "1.0.0"
__versionTime__ = "xx/xx/xxxx"
__author__ = "Fabien Marteau <fabien.marteau@laposte.net>"
 
import cmd, re, os, sys
import os.path

import time
import datetime

from scipy import *
from pylab import figure, show, setp
from numpy import *

COEF_VOLTAGE = 0.7174
COEF_CURRENT = 0.9375

TENSION_LSB = 0.004934 # volts
CURRENT_LSB = 0.184    # miliAmpere
WIND = 1.1176 # m.s-1/Hz
SURFACE = 0.01184 # m2

class weathertemp():
    def __init__(self,localpath="/home/fabien/.weathertemp/",webarchive="http://fabienmarteau.free.fr/stationmeteo/archive/",step=30):
        self.LOCALPATH=localpath
        self.WEBARCHIVE=webarchive
        self.STEP=step
        if(not os.path.exists(self.LOCALPATH)):
            os.mkdir(self.LOCALPATH) 
            os.mkdir(str(self.LOCALPATH) + "/" + "month")
            os.mkdir(str(self.LOCALPATH) + "/" + "day")
            print "file " + str(self.LOCALPATH)+"month/ created"

    def opendatafile(self,fname):
      """ open the data file download it if necessary
      """
      import os 
      if(not os.path.exists(str(self.LOCALPATH) + "/day/"+ fname)):
        # if the daylog file does not exist, we download the month tar.gz file
        t = datetime.datetime.now()
        date = fname.split("_")
        fmonthname = str(date[0]) + "_" + str(date[1]) + ".tar.gz"
        if(int(time.mktime(t.timetuple())) - int(os.stat(str(self.LOCALPATH)+"/month/"+fmonthname)[9]) > 24*60*20):
            os.system("cd "+str(self.LOCALPATH)+"/month/;"+"wget " + str(self.WEBARCHIVE)+"/"+fmonthname)
            os.system("cd " + str(self.LOCALPATH) + "/day/; tar -zxvf " + "../month/" + fmonthname)
      if(not os.path.exists(str(self.LOCALPATH) + "/day/"+ fname)):
        # if the daylog file does not exist after downloading month -> error
        print "No data this day " + fname
        return -1
      return open(str(self.LOCALPATH) + "/day/"+ fname,'r')

    def getoneentry(self,date_epoch):
      """ return the nearest entry or -1 on error
      """
      nulltuple = [  '-1',  '-1',  '-1',  '-1',  '-1', '-1'] 
      nulltuple[0]=int(date_epoch)
      t = time.localtime(date_epoch);
      fname = '%04d'%t[0] + "_" + '%02d'%t[1] + "_" + '%02d'%t[2]
      file = self.opendatafile(fname)
      if(file == -1):
        return nulltuple
      oldtime = 0
      for data in file:
        data = data.rstrip()
        datatuple = data.split(" ")
        if int(datatuple[0]) >= int(date_epoch):
          break
        oldtime=datatuple[0]
      if(int(datatuple[0])==int(date_epoch)):
        return datatuple
      if(int(datatuple[0]) - int(oldtime) > self.STEP):
        if(int(datatuple[0]) - int(date_epoch) > self.STEP):
          return nulltuple
        return datatuple
      return datatuple

    def datalist(self,begindate,enddate):
      """ return a list af value between two dates
      """
      list=[]
      for i in range(int(begindate),int(enddate),self.STEP):
        rawentry = self.getoneentry(i)
        list.append(rawentry)
      return list

    def average(self,list):
      """return one entry that is average of all entry in list with the last entry date
      """
      if(len(list) == 1):
            return [list[0][0],'-1','-1','-1','-1','-1']
      tuplesum = [list[-1][0],'0','0','0','0','0']
      for i in list:
        if(tuplesum[1] != '-1'):
            tuplesum[1] = str(int(tuplesum[1]) + int(i[1]))
            tuplesum[2] = str(int(tuplesum[2]) + int(i[2]))
            tuplesum[3] = str(int(tuplesum[3]) + int(i[3]))
            tuplesum[4] = str(int(tuplesum[4]) + int(i[4]))
            tuplesum[5] = str(int(tuplesum[5]) + int(i[5]))
        else:
            return [list[-1][0],'-1','-1','-1','-1','-1']
      tuplesum[1] = str(int(tuplesum[1])/len(list))
      tuplesum[2] = str(int(tuplesum[2])/len(list))
      tuplesum[3] = str(int(tuplesum[3])/len(list))
      tuplesum[4] = str(int(tuplesum[4])/len(list))
      tuplesum[5] = str(int(tuplesum[5])/len(list))
      return tuplesum

    def datalistaverage(self,number,begindate,enddate):
      """ return a list of data from begindate to enddate with number of data asked
      """
      list = []
      if(int(begindate) >= int(enddate)):
        print "begindate is upper than enddate"
        exit(0)
      numberforaverage = 1
      interval=self.STEP
      if(((int(enddate) - int(begindate))/number > int(self.STEP))):
        interval = (int(enddate) - int(begindate))/number
        print interval
        for i in range(int(begindate),int(enddate),interval):
            list.append(self.average(self.datalist(i,i + interval - self.STEP)))
        return list
      else:
        return self.datalist(begindate,enddate)


    def datetoepoch(self,year,month,day,hour,min):
      """ return date in seconds epoch
      """
      return int(time.mktime((int(year), int(month), int(day),int(hour),0,0,0,0,0)))


    def dataplot(self,list):
      """
      plot list data
      """
      import pylab
      data = array(list)
      dataint = data.astype('int')
      datafloat = dataint.astype('float')
      timeaxe = dataint[:,0]
      current = ((datafloat[:,2]/datafloat[:,1])*CURRENT_LSB) #mA
      voltage = ((datafloat[:,4]/datafloat[:,3])*TENSION_LSB) #V
      wind =    ((datafloat[:,5]/self.STEP)*WIND)    #m.s-1
      pylab.plot(timeaxe,current,timeaxe,voltage,timeaxe,wind)
      pylab.grid(True)
      pylab.show()

    def datamultiplot(self,list):
      """
      plot multi graph
      """
      import pylab
      from pylab import figure,show, setp

       
      data = array(list)
      dataint = data.astype('int')
      datafloat = dataint.astype('float')
      timeaxe = dataint[:,0]
      current = ((datafloat[:,2]/datafloat[:,1])*CURRENT_LSB) #mA
      voltage = ((datafloat[:,4]/datafloat[:,3])*TENSION_LSB) #V
      power = ((current[:]*COEF_CURRENT/1000) * voltage[:]*COEF_VOLTAGE)/SURFACE # W/m2

      wind =    ((datafloat[:,5]/self.STEP)*WIND)    #m.s-1
      
      fig = figure()
      yprops = dict(rotation=90,
                    horizontalalignment='right',
                    verticalalignment='center',
                    x=-0.01)
      axprops = dict()

#      ax1 = fig.add_axes([0.1, 0.3, 0.8, 0.2], **axprops)
#      ax1.plot(timeaxe, current,'y')
#      ax1.set_ylabel('courant (mA)', **yprops)
#      setp(ax1.get_xticklabels(), visible=False)

      # force x axes to remain in register, even with toolbar navigation
      ax2 = fig.add_axes([0.1, 0.5, 0.8, 0.4], **axprops)

      ax2.plot(timeaxe, power,'y')
      ax2.set_ylabel('power (W/m2)', **yprops)

      ax3 = fig.add_axes([0.1, 0.1, 0.8, 0.4], **axprops)
      ax3.plot(timeaxe , wind,'b')
      ax3.set_ylabel('wind (m/s)', **yprops)

      # turn off x ticklabels for all but the lower axes
      setp(ax2.get_xticklabels(), visible=False)

      show()

if __name__ == "__main__":
    print dir(weathertemp)
    db = weathertemp()
    print db.datetoepoch(2008,2,8,0,0)
    yesterday = db.datalistaverage(500,db.datetoepoch(2008,3,1,1,0),db.datetoepoch(2008,3,31,23,0))
    db.datamultiplot(yesterday)

